package io.youngledo.usb.license;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.youngledo.usb.util.DialogUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;

import java.io.File;
import java.nio.file.Files;
import java.util.Optional;

/// 许可证激活对话框
///
/// 提供图形界面让用户激活专业版许可证。
/// 支持两种激活方式：
/// 1. 导入许可证文件（license.json）
/// 2. 输入许可证密钥（暂未实现在线验证）
public class LicenseActivationDialog {

    private static final ObjectMapper objectMapper = createObjectMapper();

    private static ObjectMapper createObjectMapper() {
        var mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        return mapper;
    }

    /// 显示许可证激活对话框
    ///
    /// @return 如果激活成功返回true
    public static boolean show() {
        var dialog = new Dialog<Boolean>();
        dialog.setTitle("激活专业版许可证");
        dialog.setHeaderText(null);
        DialogUtils.applyFlatStyle(dialog);

        // 创建对话框内容
        var content = createContent(dialog);
        dialog.getDialogPane().setContent(content);

        // 添加按钮
        var closeButton = new ButtonType("关闭", ButtonBar.ButtonData.CANCEL_CLOSE);
        dialog.getDialogPane().getButtonTypes().add(closeButton);

        // 设置结果转换器 - 将 ButtonType 转换为 Boolean
        dialog.setResultConverter(buttonType -> {
            // 默认返回false，除非在激活成功时通过 dialog.setResult(true) 显式设置
            return false;
        });

        // 显示对话框
        Optional<Boolean> optionalBoolean = dialog.showAndWait();
        return optionalBoolean.orElse(false);
    }

    /// 创建对话框内容
    private static VBox createContent(Dialog<Boolean> dialog) {
        var vbox = new VBox(20);
        vbox.setPadding(new Insets(20));
        vbox.setAlignment(Pos.TOP_LEFT);
        vbox.setPrefWidth(500);

        // 标题说明
        var titleLabel = new Label("激活专业版许可证");
        titleLabel.getStyleClass().add("title");

        var descLabel = new Label("请选择激活方式：");

        // 方式1：导入许可证文件
        var fileSection = createFileImportSection(dialog);

        // 分隔线
        var separator = new Separator();

        // 当前许可证状态
        var currentSection = createCurrentLicenseSection();

        vbox.getChildren().addAll(
                titleLabel,
                descLabel,
                fileSection,
                separator,
                currentSection
        );

        return vbox;
    }

    /// 创建文件导入区域
    private static VBox createFileImportSection(Dialog<Boolean> dialog) {
        var vbox = new VBox(10);

        var methodLabel = new Label("方式一：导入许可证文件");
        methodLabel.getStyleClass().add("bold-text");

        var hintLabel = new Label("选择您购买后收到的 license.json 文件");
        hintLabel.getStyleClass().add("small-text");

        // 文件选择按钮
        var selectButton = new Button("选择许可证文件...");
        selectButton.getStyleClass().add("button-primary");

        selectButton.setOnAction(e -> {
            var fileChooser = new FileChooser();
            fileChooser.setTitle("选择许可证文件");
            fileChooser.getExtensionFilters().add(
                    new FileChooser.ExtensionFilter("许可证文件", "*.json")
            );

            var file = fileChooser.showOpenDialog(dialog.getOwner());
            if (file != null) {
                handleLicenseFileImport(file, dialog);
            }
        });

        vbox.getChildren().addAll(methodLabel, hintLabel, selectButton);
        return vbox;
    }

    /// 创建当前许可证状态区域
    private static VBox createCurrentLicenseSection() {
        var vbox = new VBox(10);

        var statusLabel = new Label("当前许可证状态");

        var license = LicenseManager.getCurrentLicense();
        var grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(8);

        // 版本类型
        grid.add(new Label("版本："), 0, 0);
        var typeLabel = new Label(license.type().getDisplayName());
        grid.add(typeLabel, 1, 0);

        // 用户信息
        grid.add(new Label("用户："), 0, 1);
        grid.add(new Label(license.userName()), 1, 1);

        // 有效期
        grid.add(new Label("有效期："), 0, 2);
        var expiryText = license.expiryDate() == null ?
                "永久有效" :
                license.expiryDate().toString();
        grid.add(new Label(expiryText), 1, 2);

        // 启用功能数
        if (license.type() == LicenseType.PROFESSIONAL) {
            grid.add(new Label("启用功能："), 0, 3);
            grid.add(new Label(String.valueOf(license.enabledFeatures().size()) + " 项"), 1, 3);
        }

        vbox.getChildren().addAll(statusLabel, grid);
        return vbox;
    }

    /// 处理许可证文件导入
    private static void handleLicenseFileImport(File file, Dialog<Boolean> dialog) {
        try {
            // 读取文件内容
            var json = Files.readString(file.toPath());

            // 解析许可证
            var license = objectMapper.readValue(json, License.class);

            // 显示确认对话框
            var confirm = showLicenseConfirmDialog(license);
            if (!confirm) {
                return;
            }

            // 激活许可证
            boolean success = LicenseManager.activateLicense(license);

            if (success) {
                var successAlert = new Alert(Alert.AlertType.INFORMATION);
                successAlert.setTitle("激活成功");
                successAlert.setHeaderText(null);
                successAlert.setContentText(String.format("""
                        许可证已成功激活！

                        版本：%s
                        用户：%s

                        请重启应用以使所有功能生效。
                        """,
                        license.type().getDisplayName(),
                        license.userName()));
                DialogUtils.applyFlatStyle(successAlert);
                successAlert.showAndWait();

                // 关闭对话框
                dialog.setResult(true);
                dialog.close();
            } else {
                var failureAlert = new Alert(Alert.AlertType.ERROR);
                failureAlert.setTitle("激活失败");
                failureAlert.setHeaderText(null);
                failureAlert.setContentText("""
                        许可证验证失败

                        可能的原因：
                        1. 许可证文件已损坏
                        2. 许可证已过期
                        3. 许可证签名无效

                        请联系技术支持获取帮助。
                        """);
                DialogUtils.applyFlatStyle(failureAlert);
                failureAlert.showAndWait();
            }

        } catch (Exception e) {
            var errorAlert = new Alert(Alert.AlertType.ERROR);
            errorAlert.setTitle("导入失败");
            errorAlert.setHeaderText(null);
            errorAlert.setContentText("无法读取许可证文件\n\n错误信息：" + e.getMessage());
            DialogUtils.applyFlatStyle(errorAlert);
            errorAlert.showAndWait();
        }
    }

    /// 显示许可证确认对话框
    private static boolean showLicenseConfirmDialog(License license) {
        var dialog = new Alert(Alert.AlertType.CONFIRMATION);
        dialog.setTitle("确认激活");
        dialog.setHeaderText(null);
        DialogUtils.applyFlatStyle(dialog);

        var content = new VBox(10);
        content.setPadding(new Insets(10));

        var titleLabel = new Label("即将激活以下许可证：");
        titleLabel.getStyleClass().add("bold-text");

        var grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(8);

        grid.add(new Label("许可证密钥："), 0, 0);
        grid.add(new Label(license.licenseKey()), 1, 0);

        grid.add(new Label("版本类型："), 0, 1);
        grid.add(new Label(license.type().getDisplayName()), 1, 1);

        grid.add(new Label("授权用户："), 0, 2);
        grid.add(new Label(license.userName() + " (" + license.userId() + ")"), 1, 2);

        grid.add(new Label("有效期："), 0, 3);
        var expiryText = license.expiryDate() == null ?
                "永久有效" :
                "至 " + license.expiryDate().toLocalDate();
        grid.add(new Label(expiryText), 1, 3);

        if (license.machineId() != null) {
            grid.add(new Label("设备绑定："), 0, 4);
            grid.add(new Label("已绑定"), 1, 4);
        }

        content.getChildren().addAll(titleLabel, grid);
        dialog.getDialogPane().setContent(content);

        var result = dialog.showAndWait();
        return result.isPresent() && result.get() == ButtonType.OK;
    }
}
